﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Battleship
{
    class VerticalBalance
    {
        // The tich chiem nuoc
        private double waterVol;
        private double displacement;
        // Chieu chim trung binh
        private double averageDraft;
        // Hoanh do trong tam
        private double LCG;
        // Chieu cao trong tam
        private double KG;
        // Tam duong nuoc
        private double LCF;
        // Hoanh do tam noi
        private double LCB;
        // Chieu cao tam noi
        private double KB;
        // Ban kinh tam nghieng
        private double BM;
        // Momen chui 1m
        private double M_trim;
        // Momen chui tau
        private double Mch;
        // Do chui cua tau
        private double deltaT;
        // Goc chui
        private double psi;
        // Thay doi chui mui
        private double deltaTm;
        // Thay doi chui lai
        private double deltaTl;
        // Mớn nước mũi
        private double Tm;
        // Mớn nước lái
        private double Tl;
        // Chiều cao tâm nghiêng
        private double GM;
        // Momen nghiêng tàu 1 độ
        private double M1;

        private double TPC;

        // Cho lay trong ban ve
        private double c = 0.3;

        // Dùng để tính displacement
        private Dictionary<double, double> Tank_XgZg_Map = new Dictionary<double, double>()
        {
            {-30.320, 4.870}, {-33.320, 3.100}, {-25.500, 3.000}
        };
        // Giá trị nhập vào
        //private double m1, m2, m3;

        public VerticalBalance(double m1, double m2, double m3, double Mx, double My, double Mz, double m)
        {
            this.displacement = Constants.P + m + m1 + m2 + m3;

            this.waterVol = displacement / Constants.gamma;

            HydrostaticInterpolate HI = new HydrostaticInterpolate();
            this.averageDraft = HI.hydroInterpolate(waterVol, Constants.DI);

            this.LCG = (Constants.LCG * Constants.P + (Mx / m + c) * m
                            + m1 * Tank_XgZg_Map.Keys.ElementAt(0)
                            + m2 * Tank_XgZg_Map.Keys.ElementAt(1)
                            + m3 * Tank_XgZg_Map.Keys.ElementAt(2)) / displacement;
            this.KG = (Constants.Zg * Constants.P + (Mz / m + c) * m
                            + m1 * Tank_XgZg_Map.Values.ElementAt(0)
                            + m2 * Tank_XgZg_Map.Values.ElementAt(1)
                            + m3 * Tank_XgZg_Map.Values.ElementAt(2)) / displacement;
            this.LCF = HI.hydroInterpolate(waterVol, Constants.LCF);
            this.LCB = HI.hydroInterpolate(waterVol, Constants.LCB);
            this.KB = HI.hydroInterpolate(waterVol, Constants.KB);
            this.BM = HI.hydroInterpolate(waterVol, Constants.BM);
            this.TPC = HI.hydroInterpolate(waterVol, Constants.TPC);
            this.M_trim = HI.hydroInterpolate(waterVol, Constants.MTRIM);
            this.Mch = displacement * (LCG - LCB);
            this.deltaT = Mch / (M_trim * 100);
            this.psi = deltaT / Constants.L;
            this.deltaTm = (Constants.L / 2 - LCF) * psi;
            this.deltaTl = -(Constants.L / 2 + LCF) * psi;
            this.Tm = averageDraft + deltaTm;
            this.Tl = averageDraft + deltaTl;
            this.GM = KB + BM - KG;
            this.M1 = displacement * GM / 57.3;
        }

        public double WaterVol
        {
            get { return waterVol; }
            set { waterVol = value; }
        }

        public double getKG
        {
            get { return KG; }
            set { KG = value; }
        }

        public double Displacement
        {
            get { return displacement; }
            set { displacement = value; }
        }


        public double AverageDraft
        {
            get { return averageDraft; }
            set { averageDraft = value; }
        }


        public double getLCG
        {
            get { return LCG; }
            set { LCG = value; }
        }


        public double getLCF
        {
            get { return LCF; }
            set { LCF = value; }
        }

        public double getLCB
        {
            get { return LCB; }
            set { LCB = value; }
        }


        public double getM_trim
        {
            get { return M_trim; }
            set { M_trim = value; }
        }


        public double DeltaT
        {
            get { return deltaT; }
            set { deltaT = value; }
        }


        public double getTm
        {
            get { return Tm; }
            set { Tm = value; }
        }


        public double getTl
        {
            get { return Tl; }
            set { Tl = value; }
        }

        public double getTPC
        {
            get { return TPC; }
            set { TPC = value; }
        }

        public double getKB
        {
            get { return KB; }
            set { KB = value; }
        }


        public double getBM
        {
            get { return BM; }
            set { BM = value; }
        }

        public double getGM
        {
            get { return GM; }
            set { GM = value; }
        }
    }
}
